package com.xyht.sca_s.student_manage_system.modules.scheduleManagement.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.CacheUtil;
import com.xyht.sca_s.student_manage_system.common.util.TimeUtil;
import com.xyht.sca_s.student_manage_system.modules.meeting.entity.SmsMeetingRoomPredetermineApply;
import com.xyht.sca_s.student_manage_system.modules.meeting.entity.resp.SmsMeetingRoomInfoResp;
import com.xyht.sca_s.student_manage_system.modules.meeting.mapper.SmsMeetingRoomInfoMapper;
import com.xyht.sca_s.student_manage_system.modules.meeting.mapper.SmsMeetingRoomPredetermineApplyMapper;
import com.xyht.sca_s.student_manage_system.modules.meeting.util.AddMeetingUtil;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.AppTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.RangeTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.TipsRecordStatusEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.TipsTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.util.NewTipsUtil;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.entity.SmsSchedule;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.entity.SmsScheduleNotice;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.entity.SmsSchedulePersonRelation;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.entity.SmsScheduleSubscribe;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.entity.req.SmsScheduleDeleteReq;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.entity.req.SmsScheduleReadReq;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.entity.req.SmsScheduleReq;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.entity.req.SmsScheduleUpdateReq;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.entity.resp.*;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.mapper.SmsScheduleMapper;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.mapper.SmsScheduleNoticeMapper;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.mapper.SmsSchedulePersonRelationMapper;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.mapper.SmsScheduleSubscribeMapper;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.service.SmsScheduleService;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.util.ScheduleManagementUtil;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.AcceptTypeConstant.ACCEPT_TYPE_ACCEPT;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.CommonConstant.SCHEDULE_BOOLEAN_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.IsOpenFlagConstant.IS_OPEN_FLAG_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.PersonTypeConstant.PERSON_TYPE_PERSON;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.RepeatTypeConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.ScheduleTypeConstant.SCHEDULE_TYPE_MEETING;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.UpdateTypeConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.UserSubscribeTypeConstant.PERSON_TYPE_MAIN;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.UserSubscribeTypeConstant.PERSON_TYPE_SUBSCRIBE;

/**
 * <p>
 * 日程表 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2023-08-14
 */
@Service
public class SmsScheduleServiceImpl extends ServiceImpl<SmsScheduleMapper, SmsSchedule> implements SmsScheduleService {
    @Autowired
    private SmsScheduleMapper smsScheduleMapper;
    @Autowired
    private SmsSchedulePersonRelationMapper smsSchedulePersonRelationMapper;
    @Autowired
    private SmsScheduleNoticeMapper smsScheduleNoticeMapper;
    @Autowired
    private AddMeetingUtil addMeetingUtil;
    @Autowired
    private CacheUtil cacheUtil;
    @Autowired
    private ScheduleManagementUtil scheduleManagementUtil;
    @Autowired
    private SmsScheduleSubscribeMapper smsScheduleSubscribeMapper;
    @Autowired
    private NewTipsUtil newTipsUtil;

    @Autowired
    private SmsMeetingRoomInfoMapper smsMeetingRoomInfoMapper;
    @Autowired
    private SmsMeetingRoomPredetermineApplyMapper smsMeetingRoomPredetermineApplyMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Async
    public Future<ResponseResult> addSchedule(SmsScheduleReq smsScheduleReq, String user_id) {
        String event_id = "";
        try {
            if (TimeUtil.compareTwoTime(smsScheduleReq.getScheduleEndTime(), smsScheduleReq.getScheduleBeginTime()) <= 0) {
                return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
            }
            int calTimeSecond = (int) TimeUtil.calculatetimeGapSecond(smsScheduleReq.getScheduleBeginTime(), smsScheduleReq.getScheduleEndTime());

            if (!smsScheduleReq.getRepeatType().equals(REPEAT_TYPE_NEVER)) {
                if (smsScheduleReq.getRepeatEndTime() == null) {
                    return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
                }
                Date realRepeatEndTime = TimeUtil.AddYears(smsScheduleReq.getScheduleEndTime(), 1);
                realRepeatEndTime = TimeUtil.GetEndDate(realRepeatEndTime);
                long result = realRepeatEndTime.getTime() - smsScheduleReq.getRepeatEndTime().getTime();
                if (result < 0) {
                    return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.SCHEDULE_REPEAT_TIME_OVER_LIMIT));
                }
            }

            if (smsScheduleReq.getScheduleType().equals(SCHEDULE_TYPE_MEETING)) {
                if (isNullOrEmpty(smsScheduleReq.getMeetingRoomId())) {
                    return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
                }
            }

            //自定义日程 必须包含日程开始日期
            if (smsScheduleReq.getRepeatType().equals(REPEAT_TYPE_EVERY_CUSTOM)) {
                if (smsScheduleReq.getRepeatCustomWeek() == null || smsScheduleReq.getRepeatCustomWeek().size() > 7) {
                    return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
                }

                Calendar cal = Calendar.getInstance();
                cal.setTime(smsScheduleReq.getScheduleBeginTime());
                int week_index = cal.get(Calendar.DAY_OF_WEEK);

                if (!smsScheduleReq.getRepeatCustomWeek().contains(week_index)) {
                    return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
                }
            }

            String scheduleRepeatId = new Date().getTime() + "";

            //添加日程
            //是否重复日程
            if (smsScheduleReq.getRepeatType().equals(REPEAT_TYPE_NEVER)) { //非重复日程
                event_id = scheduleManagementUtil.addMeetingAndSchedule(smsScheduleReq,
                        smsScheduleReq.getScheduleBeginTime(),
                        smsScheduleReq.getScheduleEndTime(),
                        user_id,
                        scheduleRepeatId);
            } else if (smsScheduleReq.getRepeatType().equals(REPEAT_TYPE_EVERY_CUSTOM)) { //自定义日程
                //获取星期六日期
                Calendar cal = Calendar.getInstance();
                cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
                cal.set(Calendar.DATE, cal.get(Calendar.DATE) + 5);
                Date saturdayDate = cal.getTime();

                //循环一次
                int loop_times = 1;
                if (smsScheduleReq.getRepeatEndTime().getTime() > saturdayDate.getTime()) {
                    float calDay = TimeUtil.calculateTimeGapDay(smsScheduleReq.getRepeatEndTime(), saturdayDate);
                    if (calDay < 0) {
                        calDay *= -1;
                    }
                    int extra_loop = (int) Math.floor(calDay / 7) + 1;
                    loop_times += extra_loop;
                }
                for (int i = 0; i < loop_times; i++) {
                    for (Integer week : smsScheduleReq.getRepeatCustomWeek()) {
                        Calendar weekBgCal = Calendar.getInstance();
                        weekBgCal.setTime(smsScheduleReq.getScheduleBeginTime());
                        weekBgCal.set(Calendar.DAY_OF_WEEK, week);
                        Date weekBgDate = TimeUtil.AddDays(weekBgCal.getTime(), i * 7);
                        Date weekEndDate = TimeUtil.AddSeconds(weekBgDate, calTimeSecond);

                        if (weekBgDate.getTime() > smsScheduleReq.getRepeatEndTime().getTime()) {
                            continue;
                        }
                        if (smsScheduleReq.getScheduleBeginTime().getTime() > weekBgDate.getTime()) {
                            continue;
                        }

                        String id = scheduleManagementUtil.addMeetingAndSchedule(smsScheduleReq,
                                weekBgDate,
                                weekEndDate,
                                user_id,
                                scheduleRepeatId);
                        if (i == 0){
                            event_id = id;
                        }
                    }
                }
            } else { //重复日程 1：每天 2：每周 3：每月
                int loop_times = 0;
                int calDay = 0;
                if (smsScheduleReq.getRepeatEndTime().getTime() > smsScheduleReq.getScheduleBeginTime().getTime()) {
                    calDay = (int) TimeUtil.calculateTimeGapDay(smsScheduleReq.getScheduleBeginTime(),smsScheduleReq.getRepeatEndTime());
                }

                if (smsScheduleReq.getRepeatType().equals(REPEAT_TYPE_EVERY_DAY)) {
                    loop_times = calDay + 1;
                    for (int i = 0; i < loop_times; i++) {
                        Date weekBgDate = TimeUtil.AddDays(smsScheduleReq.getScheduleBeginTime(), i);
                        Date weekEndDate = TimeUtil.AddSeconds(weekBgDate, calTimeSecond);

                        if (weekBgDate.getTime() > smsScheduleReq.getRepeatEndTime().getTime()
                                && weekBgDate.getDate() > smsScheduleReq.getRepeatEndTime().getDate()) {
                            continue;
                        }

                        String id = scheduleManagementUtil.addMeetingAndSchedule(smsScheduleReq,
                                weekBgDate,
                                weekEndDate,
                                user_id,
                                scheduleRepeatId);
                        if (i == 0){
                            event_id = id;
                        }
                    }
                } else if (smsScheduleReq.getRepeatType().equals(REPEAT_TYPE_EVERY_WEEK)) {
                    int extra_loop = (int) Math.floor(calDay / 7) + 1;
                    loop_times += extra_loop;
                    for (int i = 0; i < loop_times; i++) {
                        Date weekBgDate = TimeUtil.AddDays(smsScheduleReq.getScheduleBeginTime(), i * 7);
                        Date weekEndDate = TimeUtil.AddSeconds(weekBgDate, calTimeSecond);

                        if (weekBgDate.getTime() > smsScheduleReq.getRepeatEndTime().getTime()
                                && weekBgDate.getDate() > smsScheduleReq.getRepeatEndTime().getDate()) {
                            continue;
                        }

                        String id = scheduleManagementUtil.addMeetingAndSchedule(smsScheduleReq,
                                weekBgDate,
                                weekEndDate,
                                user_id,
                                scheduleRepeatId);
                        if (i == 0){
                            event_id = id;
                        }
                    }
                } else {
                    loop_times = TimeUtil.GetDiffMonth(smsScheduleReq.getScheduleBeginTime(), smsScheduleReq.getRepeatEndTime()) + 1;
                    for (int i = 0; i < loop_times; i++) {
                        Date monthBgDate = TimeUtil.AddMonths(smsScheduleReq.getScheduleBeginTime(), i);
                        Date monthEndDate = TimeUtil.AddSeconds(monthBgDate, calTimeSecond);

                        if (monthBgDate.getTime() > smsScheduleReq.getRepeatEndTime().getTime()
                                && monthBgDate.getDate() > smsScheduleReq.getRepeatEndTime().getDate()) {
                            continue;
                        }

                        String id = scheduleManagementUtil.addMeetingAndSchedule(smsScheduleReq,
                                monthBgDate,
                                monthEndDate,
                                user_id,
                                scheduleRepeatId);
                        if (i == 0){
                            event_id = id;
                        }
                    }

                }
            }

            if (smsScheduleReq.getIsNotice() == SCHEDULE_BOOLEAN_TRUE){
                newTipsUtil.addNewTips(TipsTypeEnum.TIPS_TYPE_ENUM_MESSAGE,
                        user_id,
                        RangeTypeEnum.RANGE_TYPE_ENUM_PERSON,
                        smsScheduleReq.getPersonList(),
                        AppTypeEnum.APP_TYPE_ENUM_SCHEDULE,
                        event_id,
                        "",
                        "你有一个新的日程待查看",
                        TipsRecordStatusEnum.TIPS_RECORD_STATUS_ENUM_MESSAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            String[] dealMessage = e.getLocalizedMessage().split("：");
            String result = e.getMessage();
            if (dealMessage.length > 1) {
                result = dealMessage[dealMessage.length - 1];
            }
            return new AsyncResult<>(CommonResult.failed(result));
        }
        return new AsyncResult<>(CommonResult.success());
    }

    @Override
    public ResponseResult getScheduleListByTimeRange(Date bg_date, Date end_date, List<String> subscribe_user, String user_id) {
        if (!isNullOrEmpty(subscribe_user)) {
            if (subscribe_user.size() < 1) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
        }

        List<SmsScheduleUserResp> scheduleUserRespList = new ArrayList<>();

        //获取本人日程
        SmsUser smsUser = cacheUtil.getUserInfo(user_id);
        SmsScheduleUserResp smsScheduleUserResp = new SmsScheduleUserResp();
        if (smsUser != null) {
            smsScheduleUserResp.setRealName(smsUser.getRealName());
            smsScheduleUserResp.setUserId(smsUser.getId());
            smsScheduleUserResp.setUserPic(smsUser.getUserPic());
            smsScheduleUserResp.setUserType(PERSON_TYPE_MAIN);
        }
        //获取关联日程
        List<String> idList = smsSchedulePersonRelationMapper.selectList(new QueryWrapper<SmsSchedulePersonRelation>()
                        .select("schedule_id")
                        .lambda()
                        .eq(SmsSchedulePersonRelation::getPersonId, user_id)
                        .groupBy(SmsSchedulePersonRelation::getScheduleId))
                .stream()
                .map(SmsSchedulePersonRelation::getScheduleId)
                .collect(Collectors.toList());
        List<SmsScheduleResp> scheduleRespList = smsScheduleMapper.selectList(new QueryWrapper<SmsSchedule>()
                        .lambda()
                        .and(lambdaQuery -> {
                            lambdaQuery.eq(SmsSchedule::getScheduleCreatorId, user_id);
                            if (idList.size() > 0) {
                                lambdaQuery.or().in(SmsSchedule::getId, idList);
                            }
                        })
                        .ge(SmsSchedule::getScheduleBeginTime, bg_date)
                        .le(SmsSchedule::getScheduleBeginTime, end_date)
                        .orderByAsc(SmsSchedule::getScheduleBeginTime))
                .stream()
                .map(smsSchedule -> {
                    SmsScheduleResp smsScheduleResp = new SmsScheduleResp();
                    BeanUtils.copyProperties(smsSchedule, smsScheduleResp);

                    SmsUser user = cacheUtil.getUserInfo(smsSchedule.getScheduleCreatorId());
                    if (user != null) {
                        SmsUserInfoResp smsUserInfoResp = new SmsUserInfoResp();
                        BeanUtils.copyProperties(user, smsUserInfoResp);
                        smsScheduleResp.setCreatorInfo(smsUserInfoResp);
                    }

                    //参与者
                    List<SmsSchedulePersonRelationResp> personRelationRespList = smsSchedulePersonRelationMapper.selectList(new QueryWrapper<SmsSchedulePersonRelation>()
                                    .lambda()
                                    .eq(SmsSchedulePersonRelation::getScheduleId, smsSchedule.getId()))
                            .stream()
                            .map(person -> {
                                SmsSchedulePersonRelationResp smsSchedulePersonResp =
                                        new SmsSchedulePersonRelationResp();
                                BeanUtils.copyProperties(person, smsSchedulePersonResp);
                                SmsUser person_user = cacheUtil.getUserInfo(person.getPersonId());
                                if (person_user != null) {
                                    SmsUserInfoResp smsUserInfoResp = new SmsUserInfoResp();
                                    BeanUtils.copyProperties(person_user, smsUserInfoResp);
                                    smsSchedulePersonResp.setUserInfo(smsUserInfoResp);
                                }
                                return smsSchedulePersonResp;
                            })
                            .collect(Collectors.toList());
                    smsScheduleResp.setPersonList(personRelationRespList);

                    //本人为参与者的日程
                    List<SmsSchedulePersonRelationResp> filterPersonRelationRespList = personRelationRespList.stream()
                            .filter(person -> person.getPersonId().equals(user_id) && person.getPersonType().equals(PERSON_TYPE_PERSON))
                            .collect(Collectors.toList());
                    if (filterPersonRelationRespList.size() > 0) {
                        smsScheduleResp.setAcceptType(filterPersonRelationRespList.get(0).getAcceptType());
                    } else {
                        smsScheduleResp.setAcceptType(ACCEPT_TYPE_ACCEPT);
                    }

                    //消息通知
                    List<SmsScheduleNoticeResp> noticeRespList = smsScheduleNoticeMapper.selectList(new QueryWrapper<SmsScheduleNotice>()
                                    .lambda()
                                    .eq(SmsScheduleNotice::getScheduleId, smsSchedule.getId()))
                            .stream()
                            .map(notice -> {
                                SmsScheduleNoticeResp noticeResp = new SmsScheduleNoticeResp();
                                BeanUtils.copyProperties(notice, noticeResp);
                                return noticeResp;
                            })
                            .collect(Collectors.toList());
                    smsScheduleResp.setNoticeList(noticeRespList);

                    return smsScheduleResp;
                })
                .collect(Collectors.toList());
        smsScheduleUserResp.setScheduleList(scheduleRespList);
        scheduleUserRespList.add(smsScheduleUserResp);

        //获取订阅日程
        List<String> subscribeIdList = smsScheduleSubscribeMapper.selectList(new QueryWrapper<SmsScheduleSubscribe>()
                        .lambda()
                        .eq(SmsScheduleSubscribe::getCreatorId, user_id))
                .stream()
                .map(SmsScheduleSubscribe::getSubscribeUserId)
                .collect(Collectors.toList());
        if (isNullOrEmpty(subscribe_user) || subscribe_user.size() < 1 || subscribeIdList.size() < 1) {
            return CommonResult.success(scheduleUserRespList);
        }
        //时间段内公开日程
        List<String> openScheduleIdList = smsScheduleMapper.selectList(new QueryWrapper<SmsSchedule>()
                        .lambda()
                        .eq(SmsSchedule::getIsOpen, IS_OPEN_FLAG_TRUE)
                        .ge(SmsSchedule::getScheduleBeginTime, bg_date)
                        .le(SmsSchedule::getScheduleBeginTime, end_date))
                .stream()
                .map(SmsSchedule::getId)
                .collect(Collectors.toList());

        if (openScheduleIdList.size() < 1) {
            return CommonResult.success(scheduleUserRespList);
        }

        for (String subscribe_user_id : subscribe_user) {
            if (!subscribeIdList.contains(subscribe_user_id)) {
                continue;
            }
            SmsUser subscribeUser = cacheUtil.getUserInfo(subscribe_user_id);
            SmsScheduleUserResp smsSubscribeUserResp = new SmsScheduleUserResp();
            if (subscribeUser != null) {
                smsSubscribeUserResp.setRealName(subscribeUser.getRealName());
                smsSubscribeUserResp.setUserId(subscribeUser.getId());
                smsSubscribeUserResp.setUserPic(subscribeUser.getUserPic());
                smsSubscribeUserResp.setUserType(PERSON_TYPE_SUBSCRIBE);
            }

            List<String> subscribeScheduleIdList = smsSchedulePersonRelationMapper.selectList(new QueryWrapper<SmsSchedulePersonRelation>()
                            .lambda()
                            .in(SmsSchedulePersonRelation::getScheduleId, openScheduleIdList)
                            .eq(SmsSchedulePersonRelation::getPersonId, subscribe_user_id))
                    .stream()
                    .map(SmsSchedulePersonRelation::getScheduleId)
                    .collect(Collectors.toList());
            if (subscribeScheduleIdList.size() > 0) {
                List<SmsScheduleResp> subscribeScheduleRespList = smsScheduleMapper.selectList(new QueryWrapper<SmsSchedule>()
                                .lambda()
                                .in(SmsSchedule::getId, subscribeScheduleIdList)
                                .orderByAsc(SmsSchedule::getScheduleBeginTime))
                        .stream()
                        .map(smsSchedule -> {
                            SmsScheduleResp smsScheduleResp = new SmsScheduleResp();
                            BeanUtils.copyProperties(smsSchedule, smsScheduleResp);

                            SmsUser user = cacheUtil.getUserInfo(smsSchedule.getScheduleCreatorId());
                            if (user != null) {
                                SmsUserInfoResp smsUserInfoResp = new SmsUserInfoResp();
                                BeanUtils.copyProperties(user, smsUserInfoResp);
                                smsScheduleResp.setCreatorInfo(smsUserInfoResp);
                            }

                            //参与者
                            List<SmsSchedulePersonRelationResp> personRelationRespList = smsSchedulePersonRelationMapper.selectList(new QueryWrapper<SmsSchedulePersonRelation>()
                                            .lambda()
                                            .eq(SmsSchedulePersonRelation::getScheduleId, smsSchedule.getId()))
                                    .stream()
                                    .map(person -> {
                                        SmsSchedulePersonRelationResp smsSchedulePersonResp =
                                                new SmsSchedulePersonRelationResp();
                                        BeanUtils.copyProperties(person, smsSchedulePersonResp);
                                        SmsUser person_user = cacheUtil.getUserInfo(person.getPersonId());
                                        if (person_user != null) {
                                            SmsUserInfoResp smsUserInfoResp = new SmsUserInfoResp();
                                            BeanUtils.copyProperties(person_user, smsUserInfoResp);
                                            smsSchedulePersonResp.setUserInfo(smsUserInfoResp);
                                        }
                                        return smsSchedulePersonResp;
                                    })
                                    .collect(Collectors.toList());
                            smsScheduleResp.setPersonList(personRelationRespList);

                            //消息通知
                            List<SmsScheduleNoticeResp> noticeRespList = smsScheduleNoticeMapper.selectList(new QueryWrapper<SmsScheduleNotice>()
                                            .lambda()
                                            .eq(SmsScheduleNotice::getScheduleId, smsSchedule.getId()))
                                    .stream()
                                    .map(notice -> {
                                        SmsScheduleNoticeResp noticeResp = new SmsScheduleNoticeResp();
                                        BeanUtils.copyProperties(notice, noticeResp);
                                        return noticeResp;
                                    })
                                    .collect(Collectors.toList());
                            smsScheduleResp.setNoticeList(noticeRespList);

                            return smsScheduleResp;
                        })
                        .collect(Collectors.toList());
                smsSubscribeUserResp.setScheduleList(subscribeScheduleRespList);
                scheduleUserRespList.add(smsSubscribeUserResp);
            }
        }
        return CommonResult.success(scheduleUserRespList);
    }

    @Override
    public ResponseResult getScheduleDetail(String schedule_id) {
        if (isNullOrEmpty(schedule_id)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsSchedule smsSchedule = smsScheduleMapper.selectById(schedule_id);
        if (smsSchedule == null) {
            return CommonResult.failed(CommonCodeEnum.SCHEDULE_NOT_EXIST);
        }

        SmsScheduleResp smsScheduleResp = new SmsScheduleResp();
        BeanUtils.copyProperties(smsSchedule, smsScheduleResp);

        SmsUser user = cacheUtil.getUserInfo(smsSchedule.getScheduleCreatorId());
        if (user != null) {
            SmsUserInfoResp smsUserInfoResp = new SmsUserInfoResp();
            BeanUtils.copyProperties(user, smsUserInfoResp);
            smsScheduleResp.setCreatorInfo(smsUserInfoResp);
        }

        //参与者
        List<SmsSchedulePersonRelationResp> personRelationRespList = smsSchedulePersonRelationMapper.selectList(new QueryWrapper<SmsSchedulePersonRelation>()
                        .lambda()
                        .eq(SmsSchedulePersonRelation::getScheduleId, smsSchedule.getId()))
                .stream()
                .map(person -> {
                    SmsSchedulePersonRelationResp smsSchedulePersonResp =
                            new SmsSchedulePersonRelationResp();
                    BeanUtils.copyProperties(person, smsSchedulePersonResp);
                    SmsUser person_user = cacheUtil.getUserInfo(person.getPersonId());
                    if (person_user != null) {
                        SmsUserInfoResp smsUserInfoResp = new SmsUserInfoResp();
                        BeanUtils.copyProperties(person_user, smsUserInfoResp);
                        smsSchedulePersonResp.setUserInfo(smsUserInfoResp);
                    }
                    return smsSchedulePersonResp;
                })
                .collect(Collectors.toList());
        smsScheduleResp.setPersonList(personRelationRespList);

        //消息通知
        List<SmsScheduleNoticeResp> noticeRespList = smsScheduleNoticeMapper.selectList(new QueryWrapper<SmsScheduleNotice>()
                        .lambda()
                        .eq(SmsScheduleNotice::getScheduleId, smsSchedule.getId()))
                .stream()
                .map(notice -> {
                    SmsScheduleNoticeResp noticeResp = new SmsScheduleNoticeResp();
                    BeanUtils.copyProperties(notice, noticeResp);
                    return noticeResp;
                })
                .collect(Collectors.toList());
        smsScheduleResp.setNoticeList(noticeRespList);

        //会议室信息
        String meetingApplyId = smsSchedule.getScheduleMeetingId();
        if (!isNullOrEmpty(meetingApplyId)){
            SmsMeetingRoomPredetermineApply meetingRoomPredetermineApply = smsMeetingRoomPredetermineApplyMapper.selectById(meetingApplyId);
            if (meetingRoomPredetermineApply!=null){
                SmsMeetingRoomInfoResp smsMeetingRoomInfo =addMeetingUtil.getMeetingRoomInfo(meetingRoomPredetermineApply.getMeetingRoomId());
                smsScheduleResp.setMeetingRoomInfo(smsMeetingRoomInfo);
            }
        }
        return CommonResult.success(smsScheduleResp);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Async
    public Future<ResponseResult> updateSchedule(SmsScheduleUpdateReq smsScheduleReq, String user_id) {
        try {
            if (!smsScheduleReq.getUpdateType().equals(UPDATE_TYPE_THIS)) {
                return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
            }

            SmsSchedule smsSchedule = smsScheduleMapper.selectById(smsScheduleReq.getId());
            if (smsSchedule == null) {
                return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.SCHEDULE_NOT_EXIST));
            }

            if (!smsSchedule.getScheduleCreatorId().equals(user_id)) {
                return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.SCHEDULE_USER_DENY));
            }

            //修改会议
            if (!isNullOrEmpty(smsSchedule.getScheduleMeetingId())) {
                addMeetingUtil.updateMeeting(smsSchedule.getScheduleMeetingId(),
                        smsScheduleReq.getMeetingRoomId(),
                        smsScheduleReq.getScheduleTopic(),
                        smsScheduleReq.getScheduleBeginTime(),
                        smsScheduleReq.getScheduleEndTime(),
                        smsScheduleReq.getPersonList(),
                        user_id);
            }

            //修改日程
            SmsSchedule updateSchedule = new SmsSchedule();
            BeanUtils.copyProperties(smsSchedule, updateSchedule);
            BeanUtils.copyProperties(smsScheduleReq, updateSchedule);
            updateSchedule.setId(null);
            updateSchedule.setScheduleRepeatId(null);
            scheduleManagementUtil.deleteScheduleAndMeeting(smsScheduleReq.getId(), null);

            String event_id = scheduleManagementUtil.addSingleSchedule(updateSchedule,
                    smsScheduleReq.getPersonList(),
                    smsScheduleReq.getNoticeList(),
                    user_id);

            if (smsScheduleReq.getIsNotice() == SCHEDULE_BOOLEAN_TRUE){
                newTipsUtil.addNewTips(TipsTypeEnum.TIPS_TYPE_ENUM_MESSAGE,
                        user_id,
                        RangeTypeEnum.RANGE_TYPE_ENUM_PERSON,
                        smsScheduleReq.getPersonList(),
                        AppTypeEnum.APP_TYPE_ENUM_SCHEDULE,
                        event_id,
                        null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            String[] dealMessage = e.getLocalizedMessage().split("：");
            String result = e.getMessage();
            if (dealMessage.length > 1) {
                result = dealMessage[dealMessage.length - 1];
            }
            return new AsyncResult<>(CommonResult.failed(result));
        }
        return new AsyncResult<>(CommonResult.success());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Async
    public Future<ResponseResult> deleteSchedule(SmsScheduleDeleteReq smsScheduleReq, String user_id) {
        try {
            SmsSchedule smsSchedule = smsScheduleMapper.selectById(smsScheduleReq.getId());
            if (smsSchedule == null) {
                return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.SCHEDULE_NOT_EXIST));
            }

            if (!smsSchedule.getScheduleCreatorId().equals(user_id)) {
                return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.SCHEDULE_USER_DENY));
            }

            if (!smsScheduleReq.getUpdateType().equals(UPDATE_TYPE_THIS)) {
                if (isNullOrEmpty(smsSchedule.getScheduleRepeatId())) {
                    return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.SCHEDULE_NOT_REPEAT));
                }
            }

            if (smsScheduleReq.getUpdateType().equals(UPDATE_TYPE_THIS)) {
                scheduleManagementUtil.deleteScheduleAndMeeting(smsSchedule.getId(), smsSchedule.getScheduleMeetingId());
            } else if (smsScheduleReq.getUpdateType().equals(UPDATE_TYPE_THIS_AND_FOLLOW)) {
                List<SmsSchedule> smsScheduleList = smsScheduleMapper.selectList(new QueryWrapper<SmsSchedule>()
                        .lambda()
                        .eq(SmsSchedule::getScheduleRepeatId, smsSchedule.getScheduleRepeatId())
                        .ge(SmsSchedule::getScheduleBeginTime, smsSchedule.getScheduleBeginTime()));
                if (smsScheduleList != null && smsScheduleList.size() > 0) {
                    for (SmsSchedule schedule : smsScheduleList) {
                        scheduleManagementUtil.deleteScheduleAndMeeting(schedule.getId(), schedule.getScheduleMeetingId());
                    }
                }
            } else if (smsScheduleReq.getUpdateType().equals(UPDATE_TYPE_ALL)) {
                List<SmsSchedule> smsScheduleList = smsScheduleMapper.selectList(new QueryWrapper<SmsSchedule>()
                        .lambda()
                        .eq(SmsSchedule::getScheduleRepeatId, smsSchedule.getScheduleRepeatId()));
                if (smsScheduleList != null && smsScheduleList.size() > 0) {
                    for (SmsSchedule schedule : smsScheduleList) {
                        scheduleManagementUtil.deleteScheduleAndMeeting(schedule.getId(), schedule.getScheduleMeetingId());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            String[] dealMessage = e.getLocalizedMessage().split("：");
            String result = e.getMessage();
            if (dealMessage.length > 1) {
                result = dealMessage[dealMessage.length - 1];
            }
            return new AsyncResult<>(CommonResult.failed(result));
        }
        return new AsyncResult<>(CommonResult.success());
    }

    @Override
    public ResponseResult scheduleRead(SmsScheduleReadReq smsScheduleReq, String user_id) {
        if (isNullOrEmpty(smsScheduleReq.getId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsSchedule smsSchedule = smsScheduleMapper.selectById(smsScheduleReq.getId());
        if (smsSchedule == null) {
            return CommonResult.failed(CommonCodeEnum.SCHEDULE_NOT_EXIST);
        }

        SmsSchedulePersonRelation personRelation = smsSchedulePersonRelationMapper.selectOne(new QueryWrapper<SmsSchedulePersonRelation>()
                .lambda()
                .eq(SmsSchedulePersonRelation::getScheduleId, smsScheduleReq.getId())
                .eq(SmsSchedulePersonRelation::getPersonId, user_id));
        if (personRelation == null){
            return CommonResult.failed(CommonCodeEnum.SCHEDULE_INFO_CHANGED);
        }
        SmsSchedulePersonRelation updatePerson = new SmsSchedulePersonRelation();
        updatePerson.setId(personRelation.getId());
        updatePerson.setAcceptType(ACCEPT_TYPE_ACCEPT);
        smsSchedulePersonRelationMapper.updateById(updatePerson);
        return CommonResult.success();
    }


}
